package hr.ctg.domain.model;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Immutable;
import org.hibernate.validator.NotNull;

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Immutable
@Table(name = "zupanija")
@NamedQueries( {
		@NamedQuery(name = "Zupanija.findAll", query = "select z from Zupanija z"),
		@NamedQuery(name = "Zupanija.findByObjekti", query = "SELECT DISTINCT z FROM Objekt o JOIN o.mjesto m JOIN m.zupanija z"),
		@NamedQuery(name = "Zupanija.findByNazivMjesta", query = "select z from Zupanija z join z.mjestos m where m.naziv = ?")

})
public class Zupanija implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8179138613440395744L;
	private int idZupanje;
	private String naziv;
	private Double longituda;
	private Double latituda;
	private Integer zoom;
	private String www;
	private Set<Mjesto> mjestos = new HashSet<Mjesto>(0);
	private Set<Opis> opisZupanijes = new HashSet<Opis>(0);

	public Zupanija() {
	}

	public Zupanija(final int idZupanije) {
		this.idZupanje = idZupanije;
	}

	public Zupanija(final int idZupanje, final String naziv) {
		this.idZupanje = idZupanje;
		this.naziv = naziv;
	}

	public Zupanija(final int idZupanje, final String naziv,
			final Set<Mjesto> mjestos) {
		this.idZupanje = idZupanje;
		this.naziv = naziv;
		this.mjestos = mjestos;
	}

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id_zupanje", unique = true, nullable = false)
	@NotNull
	public int getIdZupanje() {
		return idZupanje;
	}

	public void setIdZupanje(final int idZupanje) {
		this.idZupanje = idZupanje;
	}

	@Column(name = "naziv", nullable = false)
	@NotNull
	public String getNaziv() {
		return naziv;
	}

	public void setNaziv(final String naziv) {
		this.naziv = naziv;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "zupanija")
	public Set<Mjesto> getMjestos() {
		return mjestos;
	}

	public void setMjestos(final Set<Mjesto> mjestos) {
		this.mjestos = mjestos;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + idZupanje;
		return result;
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		final Zupanija other = (Zupanija) obj;
		if (idZupanje != other.getIdZupanje()) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return Integer.toString(idZupanje);
	}

	@Column(name = "longituda")
	public Double getLongituda() {
		return longituda;
	}

	public void setLongituda(final Double longituda) {
		this.longituda = longituda;
	}

	@Column(name = "latituda")
	public Double getLatituda() {
		return latituda;
	}

	public void setLatituda(final Double latituda) {
		this.latituda = latituda;
	}

	@Column(name = "zoom")
	public Integer getZoom() {
		return zoom;
	}

	public void setZoom(final Integer zoom) {
		this.zoom = zoom;
	}

	@Column(name = "www")
	public String getWww() {
		return www;
	}

	public void setWww(final String www) {
		this.www = www;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "zupanija")
	public Set<Opis> getOpisZupanijes() {
		return opisZupanijes;
	}

	public void setOpisZupanijes(final Set<Opis> opisZpanijes) {
		opisZupanijes = opisZpanijes;
	}

	public Opis getOpis(final String currentLanguage) {
		if (opisZupanijes != null) {
			for (final Opis opisObjekta : opisZupanijes) {
				if (opisObjekta.getJezik().getOznaka().equals(currentLanguage)) {
					return opisObjekta;
				}
			}
		}
		return null;
	}
}
